﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using SilverLightApp.DataHelperService;
using System.Windows.Browser;

namespace SilverLightApp
{
  public partial class TopCountriesAfflicted : Page
  {
    public string cause = "NA";
    public int chosenYear = -1;
    public delegate void SetRectangle(object stat, double height);
    public delegate void LookForUpdates();
    public DataHelperClient dataHelperClient = new DataHelperClient();
    public double maxCount = 0;
    HtmlDocument doc = null;
    public string country = "NA";

    double baseHeight = 0;

    public TopCountriesAfflicted()
    {
      InitializeComponent();
      
      dataHelperClient.GetCountsPerCountryCompleted += new EventHandler<GetCountsPerCountryCompletedEventArgs>(dataHelperClient_GetCountsPerCountryCompleted);
      dataHelperClient.GetCountsForCountryCompleted += new EventHandler<GetCountsForCountryCompletedEventArgs>(dataHelperClient_GetCountsForCountryCompleted);
      doc = HtmlPage.Document;
      HtmlElement chosenCountry = doc.GetElementById("countryName");
      country = chosenCountry.GetAttribute("value");
      System.Threading.Thread updaterThread = new System.Threading.Thread(UpdateChecker);
      updaterThread.Start();
    }

    void dataHelperClient_GetCountsForCountryCompleted(object sender, GetCountsForCountryCompletedEventArgs e)
    {
      string elementName = "tbCause0";
      TextBlock block = (TextBlock)LayoutRoot.FindName(String.Format(elementName));
      block.Text = country;
      double factor = (double)360 / maxCount;
      elementName = "rectStat0";
      double newHeight = new double();
      Rectangle bar = (Rectangle)LayoutRoot.FindName(elementName);
      newHeight = (int)(Double.Parse(e.Result.ToString()) * factor);
      double currHeight = bar.Height;
      System.Threading.Thread updaterThread = new System.Threading.Thread(
        unused => UpdateStat(bar, currHeight, newHeight));
      updaterThread.Start();
    }

    void dataHelperClient_GetCountsPerCountryCompleted(object sender, GetCountsPerCountryCompletedEventArgs e)
    {
      Dictionary<double, string> dict = new Dictionary<double, string>();
      List<CountPerCountry> sortedList = new List<CountPerCountry>();
      double[] percentages = new double[e.Result.Count];
      for(int i =0; i < e.Result.Count; i++)
      {
        percentages[i] = double.Parse(e.Result[i].Count);
        if (e.Result[i].Count == "0") 
          continue;
        try
        {
          dict.Add(Double.Parse(e.Result[i].Count), e.Result[i].Country);
        }
        catch
        {
          dict.Add(Double.Parse(e.Result[i].Count + 0.000001), e.Result[i].Country);
        }
      }
      Array.Sort(percentages);
      Array.Reverse(percentages);
      string country = string.Empty;
      for (int i = 0; i < 5; i++)
      {
        dict.TryGetValue(percentages[i], out country);
        CountPerCountry cpc = new CountPerCountry();
        cpc.Count = percentages[i].ToString();
        cpc.Country = country;
        sortedList.Add(cpc);
      }
      maxCount = double.Parse(sortedList[0].Count);
      PopulateYAxis();
      SetupXAxis(sortedList);
      UpdateStats(sortedList);
      dataHelperClient.GetCountsForCountryAsync(country, cause, chosenYear.ToString());
    }

    private void UpdateStats(List<CountPerCountry> sortedList)
    {
      double factor = (double)360 / maxCount;
      string elementName = "rectStat{0}";
      for (int i = 0; i < sortedList.Count; i++)
      {
        double newHeight = new double();
        Rectangle bar = (Rectangle)LayoutRoot.FindName(String.Format(elementName, i + 1));
        newHeight = (int)(Double.Parse(sortedList[i].Count) * factor);
        double currHeight = bar.Height;
        System.Threading.Thread updaterThread = new System.Threading.Thread(
            unused => UpdateStat(bar, currHeight, newHeight));
        updaterThread.Start();
      }
    }

    public void UpdateStat(Rectangle bar, double currHeight, double newHeight)
    {
      SetRectangle setRectangle = new SetRectangle(TransformRectangle);
      double step = 0;
      if (currHeight < newHeight)
      {
        while (currHeight < newHeight)
        {
          step = Math.Max((newHeight - currHeight) / 5, 3);
          currHeight = currHeight + step;
          this.Dispatcher.BeginInvoke(setRectangle, bar, currHeight);
          System.Threading.Thread.Sleep(50);
        }
      }
      else
      {
        while (currHeight > newHeight)
        {
          step = Math.Max((newHeight - currHeight) / 5, 3);
          currHeight = currHeight - step;
          this.Dispatcher.BeginInvoke(setRectangle, bar, currHeight);
          System.Threading.Thread.Sleep(50);
        }
      }
    }

    public void TransformRectangle(object obj, double i)
    {
      Rectangle rect = (Rectangle)obj;
      if(i <= 0) return;
      rect.Height = i;
    }

    private void SetupXAxis(List<CountPerCountry> sortedList)
    {
      string elementName = "tbCause{0}";
      for (int i = 0; i < sortedList.Count; i++)
      {
        TextBlock block = (TextBlock)LayoutRoot.FindName(String.Format(elementName, i + 1));
        block.Text = sortedList[i].Country;
      }
    }

    private void PopulateYAxis()
    {
      string elementName = "tbCount{0}";
      double jump = maxCount / 5;
      //int powerOf10 = (int)Math.Log10(maxCount) - 1;
      for (int i = 1; i <= 5; i++)
      {
        double multiplier = 0;
        TextBlock block = (TextBlock)LayoutRoot.FindName(String.Format(elementName, i));
        multiplier = (jump * i);
        block.Text = (multiplier).ToString().Substring(0, 5);
      }
    }

    public void getUpdates()
    {
      bool doUpdate = false;
      HtmlElement newSliderValue = doc.GetElementById("sliderValue");
      HtmlElement newChosenCause = doc.GetElementById("chosenCause");
      int newChosenYear = int.Parse(newSliderValue.GetAttribute("value"));
      if (newChosenYear != chosenYear && newChosenYear != -1)
      {
        chosenYear = newChosenYear;
        tbChosenYear.Text = "Year: " + chosenYear.ToString();
        doUpdate = true;
      }
      string newCause = newChosenCause.GetAttribute("value");
      if (newCause != cause && newCause != "NA")
      {
        cause = newCause;
        tbChosenCause.Text = "Cause: " + cause.Trim();
        doUpdate = true;
      }
      if (doUpdate)
        UpdateGraph();
    }

    public void UpdateChecker()
    {
      LookForUpdates lookForUpdate = new LookForUpdates(getUpdates);
      while (true)
      {
        this.Dispatcher.BeginInvoke(lookForUpdate);
        System.Threading.Thread.Sleep(500);
      }
    }

    private void UpdateGraph()
    {
      if(chosenYear != -1 && cause != "NA")
      {
        dataHelperClient.GetCountsPerCountryAsync(cause, chosenYear.ToString(), country);
      }
    }

    // Executes when the user navigates to this page.
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }

  }
}
